﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.Serialization;
using System.Windows.Media;

namespace Bookvar.ObjectModel
{
    /// <summary>
    /// This class represents a user in a collaboration session.
    /// </summary>
    [DataContract]
    [Serializable]
    public class CollaborationUser : IEquatable<CollaborationUser>
    {
        private Guid id;
        private string name;
        private Int32 userColorArgb;
        [SuppressMessage("Microsoft.Usage", "CA2235:MarkAllNonSerializableFields", Justification = "Using OnSerializing() and OnDeserialized() callbacks.")]
        private Color userColor;

        /// <summary>
        /// Initializes a new instance of the <see cref="CollaborationUser"/> class.
        /// </summary>
        public CollaborationUser()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CollaborationUser"/> class.
        /// </summary>
        /// <param name="id">The unique id.</param>
        /// <param name="name">The user name.</param>
        /// <param name="userColor">The color of the user.</param>
        public CollaborationUser(Guid id, string name, Color userColor)
        {
            this.id = id;
            this.name = name;
            this.userColor = userColor;
        }

        /// <summary>
        /// Gets or sets the id of the user.
        /// </summary>
        /// <value>The unique id of the user.</value>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")]
        [DataMember]
        public Guid ID
        {
            get { return id; }
            internal set { id = value; }
        }

        /// <summary>
        /// Gets or sets the name of the user.
        /// </summary>
        /// <value>The collaboration user name.</value>
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        [DataMember]
        public string Name
        {
            get { return name; }
            internal set { name = value; }
        }

        /// <summary>
        /// Gets or sets the userColor associated with the user.
        /// </summary>
        /// <value>The userColor associated with the user.</value>
        public Color UserColor
        {
            get { return userColor; }
            internal set { userColor = value; }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        [DataMember]
        private Int32 UserColorArgb
        {
            get { return userColorArgb; }
            set { userColorArgb = value; }
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "context")]
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            byte[] b = BitConverter.GetBytes(userColorArgb);
            UserColor = Color.FromArgb(b[0],
                                       b[1],
                                       b[2],
                                       b[3]);
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "context")]
        [OnSerializing]
        private void OnSerializing(StreamingContext context)
        {
            byte[] b = new byte[4];

            b[0] = UserColor.A;
            b[1] = UserColor.R;
            b[2] = UserColor.G;
            b[3] = UserColor.B;

            UserColorArgb = BitConverter.ToInt32(b, 0);
        }

        public bool Equals(CollaborationUser other)
        {
            if (other == null)
            {
                return false;
            }
            return Equals(id, other.id);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            return Equals(obj as CollaborationUser);
        }

        public override int GetHashCode()
        {
            return id.GetHashCode();
        }

        public override string ToString()
        {
            string format = "UserName: {0} UserID: {1}";
            string result = string.Format(CultureInfo.CurrentCulture, format, Name, ID);
            return result;
        }
    }
}